package com.uduemc.biso.node.web.component.operate;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import com.uduemc.biso.core.utils.JsonResult;
import com.uduemc.biso.node.core.common.entities.FormData;
import com.uduemc.biso.node.core.entities.SForm;
import com.uduemc.biso.node.core.entities.SSystem;
import com.uduemc.biso.node.core.node.config.OperateLoggerStaticModel;
import com.uduemc.biso.node.core.node.config.OperateLoggerStaticModelAction;
import com.uduemc.biso.node.core.operate.entities.OperateLog;
import com.uduemc.biso.node.web.api.component.SpringContextUtils;
import com.uduemc.biso.node.web.api.service.FormService;
import com.uduemc.biso.node.web.api.service.SystemService;

import cn.hutool.core.collection.CollUtil;

@Aspect
@Component
public class OperateLoggerFormController extends OperateLoggerController {

	@AfterReturning(pointcut = "execution(* com.uduemc.biso.node.web.api.controller.FormController.pageFormCreate(..))", returning = "returnValue")
	public void pageFormCreate(JoinPoint point, Object returnValue) throws IOException {
		if (!JsonResult.code200((JsonResult) returnValue)) {
			return;
		}
		Object[] args = point.getArgs();
		Signature signature = point.getSignature();
		String declaringTypeName = signature.getDeclaringTypeName();
		String modelName = OperateLoggerStaticModel.findModelName(declaringTypeName);
		String modelAction = OperateLoggerStaticModel.findModelAction(declaringTypeName, OperateLoggerStaticModelAction.INSERT_PAGE_FORM);

		// 参数1
		String name = (String) args[0];
		String paramString = objectMapper.writeValueAsString(args[0]);

		String content = "创建名为 " + name + " 的页面表单。";

		String returnValueString = objectMapper.writeValueAsString(returnValue);
		OperateLog log = makeOperateLog(modelName, modelAction, content, paramString, returnValueString);
		insertOperateLog(log);
	}

	@AfterReturning(pointcut = "execution(* com.uduemc.biso.node.web.api.controller.FormController.systemFormCreate(..))", returning = "returnValue")
	public void systemFormCreate(JoinPoint point, Object returnValue) throws IOException {
		if (!JsonResult.code200((JsonResult) returnValue)) {
			return;
		}
		Object[] args = point.getArgs();
		Signature signature = point.getSignature();
		String declaringTypeName = signature.getDeclaringTypeName();
		String modelName = OperateLoggerStaticModel.findModelName(declaringTypeName);
		String modelAction = OperateLoggerStaticModel.findModelAction(declaringTypeName, OperateLoggerStaticModelAction.INSERT_SYSTEM_FORM);

		// 参数1
		String name = (String) args[0];
		long systemId = (long) args[1];
		List<Object> param = new ArrayList<>();
		param.add(name);
		param.add(systemId);
		String paramString = objectMapper.writeValueAsString(param);

		String content = "创建名为 " + name + " 的系统表单。";
		if (systemId > 0) {
			SystemService systemServiceImpl = SpringContextUtils.getBean("systemServiceImpl", SystemService.class);
			SSystem sSystem = systemServiceImpl.getInfoById(systemId);
			content = "创建名为 " + name + " 的系统表单，并挂载到 " + sSystem.getName() + " 系统。";
		}

		String returnValueString = objectMapper.writeValueAsString(returnValue);
		OperateLog log = makeOperateLog(modelName, modelAction, content, paramString, returnValueString);
		insertOperateLog(log);
	}

	@AfterReturning(pointcut = "execution(* com.uduemc.biso.node.web.api.controller.FormController.pageFormUpdate(..))", returning = "returnValue")
	public void pageFormUpdate(JoinPoint point, Object returnValue) throws IOException {
		if (!JsonResult.code200((JsonResult) returnValue)) {
			return;
		}
		Object[] args = point.getArgs();
		Signature signature = point.getSignature();
		String declaringTypeName = signature.getDeclaringTypeName();
		String modelName = OperateLoggerStaticModel.findModelName(declaringTypeName);
		String modelAction = OperateLoggerStaticModel.findModelAction(declaringTypeName, OperateLoggerStaticModelAction.UPDATE_PAGE_FORM);

		// 参数1
		long id = (long) args[0];
		String name = (String) args[1];
		List<Object> param = new ArrayList<>();
		param.add(id);
		param.add(name);
		String paramString = objectMapper.writeValueAsString(param);

		String content = "修改表单名为 " + name + " 。";

		String returnValueString = objectMapper.writeValueAsString(returnValue);
		OperateLog log = makeOperateLog(modelName, modelAction, content, paramString, returnValueString);
		insertOperateLog(log);
	}

	@AfterReturning(pointcut = "execution(* com.uduemc.biso.node.web.api.controller.FormController.systemFormUpdate(..))", returning = "returnValue")
	public void systemFormUpdate(JoinPoint point, Object returnValue) throws IOException {
		if (!JsonResult.code200((JsonResult) returnValue)) {
			return;
		}
		Object[] args = point.getArgs();
		Signature signature = point.getSignature();
		String declaringTypeName = signature.getDeclaringTypeName();
		String modelName = OperateLoggerStaticModel.findModelName(declaringTypeName);
		String modelAction = OperateLoggerStaticModel.findModelAction(declaringTypeName, OperateLoggerStaticModelAction.UPDATE_SYSTEM_FORM);

		// 参数1
		long id = (long) args[0];
		String name = (String) args[1];
		List<Object> param = new ArrayList<>();
		param.add(id);
		param.add(name);
		String paramString = objectMapper.writeValueAsString(param);

		String content = "修改表单名为 " + name + " 。";

		String returnValueString = objectMapper.writeValueAsString(returnValue);
		OperateLog log = makeOperateLog(modelName, modelAction, content, paramString, returnValueString);
		insertOperateLog(log);
	}

	@AfterReturning(pointcut = "execution(* com.uduemc.biso.node.web.api.controller.FormController.pageFormDelete(..))", returning = "returnValue")
	public void pageFormDelete(JoinPoint point, Object returnValue) throws IOException {
		if (!JsonResult.code200((JsonResult) returnValue)) {
			return;
		}
		Object[] args = point.getArgs();
		Signature signature = point.getSignature();
		String declaringTypeName = signature.getDeclaringTypeName();
		String modelName = OperateLoggerStaticModel.findModelName(declaringTypeName);
		String modelAction = OperateLoggerStaticModel.findModelAction(declaringTypeName, OperateLoggerStaticModelAction.DELETE_PAGE_FORM);

		// 参数1
		long formId = (long) args[0];
		List<Object> param = new ArrayList<>();
		param.add(formId);
		String paramString = objectMapper.writeValueAsString(param);

		JsonResult jsonResult = (JsonResult) returnValue;
		FormData formData = (FormData) jsonResult.getData();

		String content = "删除 " + formData.getForm().getName() + " 表单。";

		String returnValueString = objectMapper.writeValueAsString(returnValue);
		OperateLog log = makeOperateLog(modelName, modelAction, content, paramString, returnValueString);
		insertOperateLog(log);
	}

	@AfterReturning(pointcut = "execution(* com.uduemc.biso.node.web.api.controller.FormController.systemFormDelete(..))", returning = "returnValue")
	public void systemFormDelete(JoinPoint point, Object returnValue) throws IOException {
		if (!JsonResult.code200((JsonResult) returnValue)) {
			return;
		}
		Object[] args = point.getArgs();
		Signature signature = point.getSignature();
		String declaringTypeName = signature.getDeclaringTypeName();
		String modelName = OperateLoggerStaticModel.findModelName(declaringTypeName);
		String modelAction = OperateLoggerStaticModel.findModelAction(declaringTypeName, OperateLoggerStaticModelAction.DELETE_SYSTEM_FORM);

		// 参数1
		long formId = (long) args[0];
		List<Object> param = new ArrayList<>();
		param.add(formId);
		String paramString = objectMapper.writeValueAsString(param);

		JsonResult jsonResult = (JsonResult) returnValue;
		FormData formData = (FormData) jsonResult.getData();

		String content = "删除 " + formData.getForm().getName() + " 表单。";

		String returnValueString = objectMapper.writeValueAsString(returnValue);
		OperateLog log = makeOperateLog(modelName, modelAction, content, paramString, returnValueString);
		insertOperateLog(log);
	}

	@AfterReturning(pointcut = "execution(* com.uduemc.biso.node.web.api.controller.FormController.pageInfoDelete(..))", returning = "returnValue")
	public void pageInfoDelete(JoinPoint point, Object returnValue) throws IOException {
		if (!JsonResult.code200((JsonResult) returnValue)) {
			return;
		}
		Object[] args = point.getArgs();
		Signature signature = point.getSignature();
		String declaringTypeName = signature.getDeclaringTypeName();
		String modelName = OperateLoggerStaticModel.findModelName(declaringTypeName);
		String modelAction = OperateLoggerStaticModel.findModelAction(declaringTypeName, OperateLoggerStaticModelAction.DELETE_FORM_SUBMIT);

		// 参数1
		long formInfoId = (long) args[0];
		List<Object> param = new ArrayList<>();
		param.add(formInfoId);
		String paramString = objectMapper.writeValueAsString(param);

		String content = "删除1条表单提交的数据。";

		String returnValueString = objectMapper.writeValueAsString(returnValue);
		OperateLog log = makeOperateLog(modelName, modelAction, content, paramString, returnValueString);
		insertOperateLog(log);
	}

	@AfterReturning(pointcut = "execution(* com.uduemc.biso.node.web.api.controller.FormController.mountToSystems(..))", returning = "returnValue")
	public void mountToSystems(JoinPoint point, Object returnValue) throws IOException {
		if (!JsonResult.code200((JsonResult) returnValue)) {
			return;
		}
		Object[] args = point.getArgs();
		Signature signature = point.getSignature();
		String declaringTypeName = signature.getDeclaringTypeName();
		String modelName = OperateLoggerStaticModel.findModelName(declaringTypeName);
		String modelAction = OperateLoggerStaticModel.findModelAction(declaringTypeName, OperateLoggerStaticModelAction.MOUNT_FORM);

		// 参数1
		long formId = (long) args[0];
		String systemIds = (String) args[1];
		List<Object> param = new ArrayList<>();
		param.add(formId);
		param.add(systemIds);
		String paramString = objectMapper.writeValueAsString(param);

		JsonResult jsonResult = (JsonResult) returnValue;
		@SuppressWarnings("unchecked")
		List<SSystem> listSystem = (List<SSystem>) jsonResult.getData();

		FormService formServiceImpl = SpringContextUtils.getBean("formServiceImpl", FormService.class);
		SForm sForm = formServiceImpl.getCurrentInfo(formId);
		if (sForm == null) {
			return;
		}

		String content = "挂载 " + sForm.getName() + " 表单。";
		List<String> mapSystemName = CollUtil.map(listSystem, item -> item.getName(), true);
		if (CollUtil.isNotEmpty(mapSystemName)) {
			String join = CollUtil.join(mapSystemName, "、");
			content = "挂载 " + sForm.getName() + " 表单到系统 " + join;
		}

		String returnValueString = objectMapper.writeValueAsString(returnValue);
		OperateLog log = makeOperateLog(modelName, modelAction, content, paramString, returnValueString);
		insertOperateLog(log);
	}

}
